package cn.broadsense.web.controller;

import cn.broadsense.biz.domain.Channel;
import cn.broadsense.biz.domain.CollectDataTask;
import cn.broadsense.biz.domain.CollectDataTaskChannel;
import cn.broadsense.biz.dto.Channel3dDataDto;
import cn.broadsense.biz.dto.StatisticsTaskStatusDTO;
import cn.broadsense.biz.service.ChannelService;
import cn.broadsense.biz.service.CollectDataTaskChannelService;
import cn.broadsense.biz.service.CollectDataTaskService;
import cn.broadsense.common.annotation.Log;
import cn.broadsense.common.annotation.RepeatSubmit;
import cn.broadsense.common.constant.HttpStatus;
import cn.broadsense.common.core.domain.R;
import cn.broadsense.common.core.page.TableDataInfoResult;
import cn.broadsense.common.enums.BusinessType;
import cn.broadsense.common.enums.OperatorType;
import cn.broadsense.common.exception.ServiceException;
import cn.broadsense.common.utils.SecurityUtils;
import cn.broadsense.web.controller.body.Channel3dDataBody;
import cn.broadsense.web.controller.query.CollectDataTaskQuery;
import cn.broadsense.web.controller.vo.CollectDataTaskVO;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;

/**
 * @author huangjinshi
 * @description
 * @createDate 2023-09-12 11:59:32
 */
@Slf4j
@RestController
@RequestMapping("/api/v1/task")
@Api(tags = "任务模块")
public class CollectDataTaskController {

    @Autowired
    private CollectDataTaskService collectDataTaskService;

    @Autowired
    private CollectDataTaskChannelService collectDataTaskChannelService;

    @Autowired
    private ChannelService channelService;

    @Autowired
    private PlatformTransactionManager transactionManager;

    @GetMapping("/statistics")
    @ApiOperation("获取任务状态统计数据")
    public R<StatisticsTaskStatusDTO> getTaskCountStatistics() {
        StatisticsTaskStatusDTO data = collectDataTaskService.statisticsTaskStatus(SecurityUtils.getUserId());
        return R.ok(data);
    }


    /**
     * 获取任务列表
     *
     * @param query
     * @return
     */
    @GetMapping("/list")
    @ApiOperation("获取任务列表")
    public TableDataInfoResult<List<CollectDataTask>> getUnfinishedTaskList(CollectDataTaskQuery query) {
        CollectDataTask task = CollectDataTask.builder()
                .status(query.getStatus()).statusList(query.getStatusList()).name(query.getName())
                .queryStartTime(query.getStartTime()).queryEndTime(query.getEndTime())
                .build();
        Page<CollectDataTask> page = new Page<>(query.getPageNum(), query.getPageSize());
        Page<CollectDataTask> unfinishedTaskList = collectDataTaskService.getUnfinishedTaskList(page, task);
        return TableDataInfoResult.ok(unfinishedTaskList.getRecords(), unfinishedTaskList.getTotal());
    }

    /**
     * 获取任务详情
     *
     * @param id
     * @return
     */
    @ApiOperation("获取任务详情")
    @GetMapping("/{id}")
    public R<CollectDataTaskVO> getInfo(@PathVariable Long id) {
        CollectDataTask task = collectDataTaskService.getById(id);
        if (task == null) {
            return R.fail(HttpStatus.NOT_FOUND, "当前任务不存在");
        } else {
            if (!SecurityUtils.getUserId().equals(task.getCollectUserId())) {
                return R.fail(HttpStatus.UNAUTHORIZED, "当前任务不属于您");
            }
        }
        List<CollectDataTaskChannel> channelList = collectDataTaskChannelService.getListByCollectDataTaskId(task.getId());
        CollectDataTaskVO data = new CollectDataTaskVO(task, channelList);
        if (task.getReadStatus().equals(0)) {
            task.setReadStatus(1);
            collectDataTaskService.updateById(task);
        }
        return R.ok(data);
    }


    /**
     * 获取点位详情
     *
     * @param id
     * @param channelId
     * @return
     */
    @ApiOperation("获取点位详情")
    @GetMapping("/{id}/channel/{channelId}")
    public R<Channel> getChannelInfo(@PathVariable Long id, @PathVariable Long channelId) {

        CollectDataTask collectDataTask = collectDataTaskService.getById(id);
        if (collectDataTask == null) {
            return R.fail(HttpStatus.NOT_FOUND, "当前任务不存在");
        } else {
            if (!SecurityUtils.getUserId().equals(collectDataTask.getCollectUserId())) {
                return R.fail(HttpStatus.UNAUTHORIZED, "当前任务不属于您");
            }
        }

        CollectDataTaskChannel collectDataTaskChannel = collectDataTaskChannelService.getByChannelIdAndCollectDataTaskId(channelId, id);
        if (collectDataTaskChannel == null) {
            return R.fail(HttpStatus.BAD_REQUEST, "当前任务未分配当前点位");
        }
        Channel channel = channelService.getDetails(channelId);
        if (channel == null) {
            return R.fail(HttpStatus.NOT_FOUND, "当前点位不存在");
        }
        Channel3dDataDto collectData = collectDataTaskChannel.getCollectData();
        log.info("collectData:{}", collectData);
        if (collectData != null) {
            channel.setChannel3dData(collectData);
        }

        return R.ok(channel);
    }


    /**
     * 上传点位采集信息
     *
     * @param id
     * @param channelId
     * @param body
     * @return
     */
    @ApiOperation("上传点位采集信息")
    @PostMapping("/{id}/channel/{channelId}")
    @RepeatSubmit(interval = 3000, message = "上传点位采集信息过于频繁")
    @Log(title = "信息采集", businessType = BusinessType.INSERT, operatorType = OperatorType.MOBILE)
    public R uploadChannelInfo(@PathVariable Long id, @PathVariable Long channelId, @Validated @RequestBody Channel3dDataBody body) {
        DefaultTransactionDefinition defaultTransactionDefinition = new DefaultTransactionDefinition();
        TransactionStatus transactionStatus = transactionManager.getTransaction(defaultTransactionDefinition);
        CollectDataTask collectDataTask = collectDataTaskService.getById(id);
        if (collectDataTask == null) {
            return R.fail(HttpStatus.NOT_FOUND, "当前任务不存在");
        } else {
            if (!SecurityUtils.getUserId().equals(collectDataTask.getCollectUserId())) {
                return R.fail("当前任务不属于您");
            }
            if (collectDataTask.getStatus().equals(4)) {
                return R.fail("当前任务已经通过，请勿重复提交");
            }
            if (collectDataTask.getStatus().equals(5)) {
                return R.fail("当前任务已经关闭，请勿重复提交");
            }
        }
        Channel channel = channelService.getById(channelId);
        if (channel == null) {
            return R.fail(HttpStatus.NOT_FOUND, "当前点位不存在");
        }
        CollectDataTaskChannel collectDataTaskChannel = collectDataTaskChannelService.getByChannelIdAndCollectDataTaskId(channelId, id);
        if (collectDataTaskChannel == null) {
            return R.fail(HttpStatus.BAD_REQUEST, "当前任务未分配当前点位");
        } else {
            if (collectDataTaskChannel.getStatus().equals(1)) {
                return R.fail(HttpStatus.BAD_REQUEST, "当前提交的点位信息已通过，请勿重复提交");
            }
        }
        Channel3dDataDto collectData = collectDataTaskChannel.getCollectData();
        if (collectData == null) {
            collectData = new Channel3dDataDto();
        }
        String pitchAngle = body.getPitchAngle();
        if (StrUtil.isNotEmpty(pitchAngle)) {
            if (NumberUtil.isNumber(pitchAngle)) {
                R.fail(HttpStatus.BAD_REQUEST, "俯仰角只能填写数字，区间在0-360");
            }
            int i = Integer.parseInt(pitchAngle);
            if (i < 0 || i > 360) {
                R.fail(HttpStatus.BAD_REQUEST, "俯仰角的区间在0-360");
            }
        }

        BeanUtils.copyProperties(body, collectData);
        collectData.setPole(body.getPole());
        collectData.setChannelId(channelId);
        collectData.setChannelName(channel.getChannelName());
        collectData.setPoleHeight(body.getPoleHeight());
        collectDataTaskChannel.setCollectData(collectData);
        collectDataTaskChannel.setUpdateTime(new Date());
        collectDataTaskChannel.setStatus(3);
        try {
            collectDataTaskChannelService.updateById(collectDataTaskChannel);
            if (collectDataTask.getTaskStatus().equals(1)) {
                collectDataTask.setTaskStatus(2);
                collectDataTaskService.updateById(collectDataTask);
            }
            transactionManager.commit(transactionStatus);
        } catch (Exception e) {
            transactionManager.rollback(transactionStatus);
            log.error(e.getMessage());
            return R.fail("操作失败");
        }
        return R.ok();
    }

    /**
     * 提交任务审核
     */
    @ApiOperation("提交任务审核")
    @PostMapping("/{id}")
    public R uploadTask(@PathVariable Long id) {
        CollectDataTask collectDataTask = collectDataTaskService.getById(id);
        if (collectDataTask == null) {
            return R.fail(HttpStatus.NOT_FOUND, "当前任务不存在");
        } else {
            if (!SecurityUtils.getUserId().equals(collectDataTask.getCollectUserId())) {
                return R.fail(HttpStatus.UNAUTHORIZED, "当前任务不属于您");
            }
            if (collectDataTask.getStatus().equals(4)) {
                return R.fail(HttpStatus.BAD_REQUEST, "当前任务已经通过，请勿重复提交");
            }
            if (collectDataTask.getStatus().equals(5)) {
                return R.fail(HttpStatus.BAD_REQUEST, "当前任务已经关闭，请勿重复提交");
            }
        }
        List<CollectDataTaskChannel> channelList = collectDataTaskChannelService.getListByCollectDataTaskId(collectDataTask.getId());
        channelList.forEach(
                collectDataTaskChannel -> {
                    if (collectDataTaskChannel.getStatus().equals(0) || collectDataTaskChannel.getStatus().equals(2)) {
                        throw new ServiceException("尚有待修改数据的点位，请继续完善");
                    }
                }
        );
        collectDataTask.setSubmissionTime(new Date());
        collectDataTask.setStatus(2);
        collectDataTask.setUpdateTime(new Date());
        collectDataTaskService.updateById(collectDataTask);
        return R.ok();
    }
}
